package com.simple.ds.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.primitives.Longs;
import com.google.gson.Gson;
import com.simple.common.entity.po.ChannelMerchantEntity;
import com.simple.common.entity.po.MerchantEntity;
import com.simple.common.entity.po.sys.*;
import com.simple.ds.service.ChannelMerchantService;
import com.simple.ds.service.ChannelService;
import com.simple.ds.service.MerchantService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;

/**
 * @author yasud
 * @date 2021年09月19日 13:17
 * @description
 */
@Service
public class ChannelServiceImpl implements ChannelService {

    @Autowired
    MerchantService merchantService;

    @Autowired
    ChannelMerchantService channelMerchantService;

    @Override
    public Map chooseChannelByExpId(Long expId, Product product) {
        MerchantEntity merchantEntity = merchantService.findMerchantByExpId(expId);
        ChannelMerchantEntity channelMerchantEntity = channelMerchantService.findByMerchantCodeAndApiCode(merchantEntity.getMerchantCode(), product.getProductCode());
        ChannelComp channelComp = createChannelComp(merchantEntity, channelMerchantEntity);
        ExampleChannel exampleChannel = createExampleChannel(merchantEntity, channelMerchantEntity, product);
        return ImmutableMap.of("left", channelComp, "right", exampleChannel);
    }

    @Override
    public ChannelComp findChannel(Long channelMerchantId) {
        ChannelMerchantEntity channelMerchantEntity = channelMerchantService.getById(channelMerchantId);
        ChannelComp channelComp = createChannelComp(null, channelMerchantEntity);
        return channelComp;
    }

    @Override
    public ChannelComp findChannelCompByFlag(String flag) {
        ChannelMerchantEntity channelMerchantEntity = channelMerchantService.getById(Longs.tryParse(flag));
        ChannelComp channelComp = createChannelComp(null, channelMerchantEntity);
        return channelComp;
    }

    @Override
    public ChannelComp findChannelCompByChannelId(Long channelId) {
        return findChannel(channelId);
    }

    private ExampleChannel createExampleChannel(MerchantEntity merchantEntity,
                                                ChannelMerchantEntity channelMerchantEntity,
                                                Product product) {
        ExampleChannel exampleChannel = new ExampleChannel();
        exampleChannel.setId(channelMerchantEntity.getId());
        exampleChannel.setChannelId(channelMerchantEntity.getId());
        exampleChannel.setChannelMerchantId(channelMerchantEntity.getId() + 1);
        exampleChannel.setApplicationId(Longs.fromByteArray(DigestUtil.sha256(merchantEntity.getMerchantCode() + "_application")));
        exampleChannel.setProductId(product.getId());
        exampleChannel.setExampleId(Longs.fromByteArray(DigestUtil.sha256(merchantEntity.getMerchantCode() + "_example")));
        exampleChannel.setEnable(true);
        return exampleChannel;
    }

    private ChannelComp createChannelComp(MerchantEntity merchantEntity, ChannelMerchantEntity channelMerchantEntity) {
        if (Objects.isNull(channelMerchantEntity)) return null;
        ChannelMerchant channelMerchant = createChannelMerchant(channelMerchantEntity);
        Channel channel = createChannel(channelMerchantEntity);
        ChannelComp channelComp = new ChannelComp();
        channelComp.setId(channel.getId());
        channelComp.setChannel(channel);
        channelComp.setName(channel.getName());
        channelComp.setChannelMerchant(channelMerchant);
        channelComp.setChannelMerchantId(channelMerchant.getId());

        channelComp.setAsyncUrl(channelMerchantEntity.getAsyncUrl());
        channelComp.setSyncUrl(channelMerchantEntity.getSyncUrl());
        channelComp.setCode(channelMerchantEntity.getChannelMerchantName());
        channelComp.setChannelFlag(channelMerchantEntity.getId() + "");
        channelComp.setChannelNotifyOkRes(channelMerchantEntity.getChannelNotifyOkRes());
        channelComp.setMid(channelMerchant.getMid());
        channelComp.setSecretKey((String)channelMerchantEntity.getChannelMerchantInfo().get("secretKey"));
        channelComp.setTerminalNo((String)channelMerchantEntity.getChannelMerchantInfo().get("terminalNo"));
        channelComp.setServiceProvider(channelMerchantEntity.getMicServiceName());
        channelComp.setEnable(channel.getEnable());
        channelComp.setPayConfigExtra(new Gson().toJson(ObjectUtils.defaultIfNull(channelMerchantEntity.getChannelMerchantInfo(), Maps.newHashMap())));
        return channelComp;
    }

    private Channel createChannel(ChannelMerchantEntity channelMerchantEntity) {
        Channel channel = new Channel();
        channel.setCreateTime(channelMerchantEntity.getCreateTime());
        channel.setType(Channel.Type.AGENCY);
        channel.setId(channelMerchantEntity.getId());
        channel.setName(channelMerchantEntity.getChannelMerchantName());
        channel.setEnable(channelMerchantEntity.getEnabled());
        return channel;
    }

    private ChannelMerchant createChannelMerchant(ChannelMerchantEntity channelMerchantEntity) {
        ChannelMerchant channelMerchant = new ChannelMerchant();
        channelMerchant.setId(channelMerchantEntity.getId());
        channelMerchant.setChannelId(channelMerchantEntity.getId());
        channelMerchant.setEnable(channelMerchantEntity.getEnabled());
        channelMerchant.setAccount(channelMerchantEntity.getMid());
        channelMerchant.setAsyncUrl(channelMerchantEntity.getAsyncUrl());
        channelMerchant.setSyncUrl(channelMerchantEntity.getSyncUrl());
        channelMerchant.setSecretKey((String)channelMerchantEntity.getChannelMerchantInfo().get("secretKey"));
        channelMerchant.setTerminalNo((String)channelMerchantEntity.getChannelMerchantInfo().get("terminalNo"));
        channelMerchant.setMid(channelMerchantEntity.getMid());
        channelMerchant.setName(channelMerchantEntity.getChannelMerchantName());
        channelMerchant.setUpdateTime(channelMerchantEntity.getUpdateTime());
        channelMerchant.setCreateTime(channelMerchantEntity.getCreateTime());

        return channelMerchant;
    }

    @Override
    public ChannelComp flexibility(Long channelMerchantId) {
        ChannelMerchantEntity merchantEntity = channelMerchantService.getById(channelMerchantId);
        if (Objects.nonNull(merchantEntity)) {
            return createChannelComp(null, merchantEntity);
        }
        return null;
    }
}
